home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-05-13 | 48.9 KB | 2,525 lines |
- Newsgroups: comp.sources.misc
- From: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
- Subject: v29i104: zsh2.2 - The Z shell, Part08/17
- Message-ID: <1992May13.160240.9562@sparky.imd.sterling.com>
- X-Md4-Signature: 63eafc497e16608b14e838d42c97828a
- Date: Wed, 13 May 1992 16:02:40 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: pfalstad@phoenix.Princeton.EDU (Paul Falstad)
- Posting-number: Volume 29, Issue 104
- Archive-name: zsh2.2/part08
- Environment: BSD
- Supersedes: zsh2.1: Volume 24, Issue 1-19
-
- #!/bin/sh
- # this is aa.08 (part 8 of zsh2.2)
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file zsh2.2/src/exec.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 8; then
- echo Please unpack part "$Scheck" next!
- exit 1
- else
- exit 0
- fi
- ) < _shar_seq_.tmp || exit 1
- if test ! -f _shar_wnt_.tmp; then
- echo 'x - still skipping zsh2.2/src/exec.c'
- else
- echo 'x - continuing file zsh2.2/src/exec.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'zsh2.2/src/exec.c' &&
- X ptr = buf;
- X }
- X } else {
- X *ptr++ = c;
- X if (++cnt == bsiz) {
- X char *pp = ncalloc(bsiz *= 2);
- X
- X memcpy(pp,buf,cnt);
- X ptr = (buf = pp)+cnt;
- X }
- X }
- X if (ptr != buf && ptr[-1] == '\n')
- X ptr[-1] = '\0';
- X else
- X *ptr = '\0';
- X if (cnt) addnode(ret,buf);
- X fclose(fin);
- X return ret;
- X}
- X
- X/* =(...) */
- X
- Xchar *getoutputfile(cmd) /**/
- Xchar *cmd;
- X{
- X#ifdef WAITPID
- Xint pid;
- X#endif
- Xchar *nam = gettemp(),*str;
- Xint tfil;
- XList list;
- X
- X if (thisjob == -1)
- X return NULL;
- X for (str = cmd; *str && *str != Outpar; str++);
- X if (!*str)
- X zerr("oops.",NULL,0);
- X *str = '\0';
- X if (!(list = parselstring(cmd)))
- X return NULL;
- X permalloc();
- X if (!jobtab[thisjob].filelist)
- X jobtab[thisjob].filelist = newlist();
- X addnode(jobtab[thisjob].filelist,ztrdup(nam));
- X heapalloc();
- X#ifdef WAITPID
- X if (pid = phork())
- X {
- X popheap();
- X waitpid(pid,NULL,WUNTRACED);
- X return nam;
- X }
- X#else
- X if (waitfork()) {
- X popheap();
- X return nam;
- X }
- X#endif
- X subsh = 1;
- X close(1);
- X entersubsh(0);
- X tfil = creat(nam,0666);
- X exiting = 1;
- X execlist(list);
- X close(1);
- X exit(0); return NULL;
- X}
- X
- X/* get a temporary named pipe */
- X
- Xchar *namedpipe() /**/
- X{
- X#ifndef NO_FIFOS
- Xchar *tnam = gettemp();
- X
- X if (mknod(tnam,0010666,0) < 0) return NULL;
- X return tnam;
- X#else
- X return NULL;
- X#endif
- X}
- X
- X/* <(...) */
- X
- Xchar *getoutproc(cmd) /**/
- Xchar *cmd;
- X{
- X#ifdef NO_FIFOS
- X zerr("doesn't look like your system supports FIFOs.",NULL,0);
- X return NULL;
- X#else
- XList list;
- Xint fd;
- Xchar *pnam,*str;
- X
- X if (thisjob == -1)
- X return NULL;
- X for (str = cmd; *str && *str != Outpar; str++);
- X if (!*str)
- X zerr("oops.",NULL,0);
- X *str = '\0';
- X pnam = namedpipe();
- X if (!pnam) return NULL;
- X permalloc();
- X if (!jobtab[thisjob].filelist)
- X jobtab[thisjob].filelist = newlist();
- X addnode(jobtab[thisjob].filelist,ztrdup(pnam));
- X heapalloc();
- X if (!(list = parselstring(cmd)))
- X return NULL;
- X if (phork())
- X {
- X popheap();
- X return pnam;
- X }
- X entersubsh(1);
- X closem();
- X fd = open(pnam,O_WRONLY);
- X if (fd == -1)
- X {
- X zerr("can't open %s: %e",pnam,errno);
- X _exit(0);
- X }
- X redup(fd,1);
- X fd = open("/dev/null",O_RDONLY);
- X redup(fd,0);
- X exiting = 1;
- X execlist(list);
- X close(1);
- X _exit(0); return NULL;
- X#endif
- X}
- X
- X/* >(...) */
- X
- Xchar *getinproc(cmd) /**/
- Xchar *cmd;
- X{
- X#ifdef NO_FIFOS
- X zerr("doesn't look like your system supports FIFOs.",NULL,0);
- X return NULL;
- X#else
- XList list;
- Xint pid,fd;
- Xchar *pnam,*str;
- X
- X if (thisjob == -1)
- X return NULL;
- X for (str = cmd; *str && *str != Outpar; str++);
- X if (!*str)
- X zerr("oops.",NULL,0);
- X *str = '\0';
- X pnam = namedpipe();
- X if (!pnam) return NULL;
- X permalloc();
- X if (!jobtab[thisjob].filelist)
- X jobtab[thisjob].filelist = newlist();
- X addnode(jobtab[thisjob].filelist,ztrdup(pnam));
- X heapalloc();
- X if (!(list = parselstring(cmd)))
- X return NULL;
- X if (pid = phork())
- X {
- X popheap();
- X return pnam;
- X }
- X entersubsh(1);
- X closem();
- X fd = open(pnam,O_RDONLY);
- X redup(fd,0);
- X exiting = 1;
- X execlist(list);
- X _exit(0); return NULL;
- X#endif
- X}
- X
- X/* > >(...) (does not use named pipes) */
- X
- Xint getinpipe(cmd) /**/
- Xchar *cmd;
- X{
- XList list;
- Xint pipes[2];
- Xchar *str = cmd;
- X
- X for (str = cmd; *str && *str != Outpar; str++);
- X if (!*str)
- X zerr("oops.",NULL,0);
- X *str = '\0';
- X if (!(list = parselstring(cmd+2)))
- X return -1;
- X mpipe(pipes);
- X if (phork())
- X {
- X popheap();
- X close(pipes[1]);
- X return pipes[0];
- X }
- X close(pipes[0]);
- X closem();
- X entersubsh(1);
- X redup(pipes[1],1);
- X exiting = 1;
- X execlist(list);
- X _exit(0); return 0;
- X}
- X
- X/* < <(...) */
- X
- Xint getoutpipe(cmd) /**/
- Xchar *cmd;
- X{
- XList list;
- Xint pipes[2];
- Xchar *str;
- X
- X for (str = cmd; *str && *str != Outpar; str++);
- X if (!*str)
- X zerr("oops.",NULL,0);
- X *str = '\0';
- X if (!(list = parselstring(cmd+2)))
- X return -1;
- X strinend();
- X mpipe(pipes);
- X if (phork())
- X {
- X popheap();
- X close(pipes[0]);
- X return pipes[1];
- X }
- X close(pipes[1]);
- X closem();
- X entersubsh(1);
- X redup(pipes[0],0);
- X exiting = 1;
- X execlist(list);
- X _exit(0); return 0;
- X}
- X
- X/* run a list, saving the current job num */
- X
- Xvoid runlist(l) /**/
- XList l;
- X{
- Xint cj = thisjob;
- X
- X execlist(l);
- X thisjob = cj;
- X}
- X
- Xchar *gettemp() /**/
- X{
- X return mktemp(dyncat(tmpprefix,"XXXXXX"));
- X}
- X
- X/* my getwd; all the other ones I tried confused the SIGCHLD handler */
- X
- Xchar *zgetwd() /**/
- X{
- Xstatic char buf0[MAXPATHLEN];
- Xchar buf3[MAXPATHLEN],*buf2 = buf0+1;
- Xstruct stat sbuf;
- Xstruct direct *de;
- XDIR *dir;
- Xino_t ino = -1;
- Xdev_t dev = -1;
- X
- X holdintr();
- X buf2[0] = '\0';
- X buf0[0] = '/';
- X for(;;)
- X {
- X if (stat(".",&sbuf) < 0)
- X {
- X chdir(buf0);
- X noholdintr();
- X return ztrdup(".");
- X }
- X ino = sbuf.st_ino;
- X dev = sbuf.st_dev;
- X if (stat("..",&sbuf) < 0)
- X {
- X chdir(buf0);
- X noholdintr();
- X return ztrdup(".");
- X }
- X if (sbuf.st_ino == ino && sbuf.st_dev == dev)
- X {
- X chdir(buf0);
- X noholdintr();
- X return ztrdup(buf0);
- X }
- X dir = opendir("..");
- X if (!dir)
- X {
- X chdir(buf0);
- X noholdintr();
- X return ztrdup(".");
- X }
- X chdir("..");
- X readdir(dir); readdir(dir);
- X while (de = readdir(dir))
- X if (de->d_ino == ino)
- X {
- X lstat(de->d_name,&sbuf);
- X if (sbuf.st_dev == dev)
- X goto match;
- X }
- X rewinddir(dir);
- X readdir(dir); readdir(dir);
- X while (de = readdir(dir))
- X {
- X lstat(de->d_name,&sbuf);
- X if (sbuf.st_dev == dev)
- X goto match;
- X }
- X noholdintr();
- X closedir(dir);
- X return ztrdup(".");
- Xmatch:
- X strcpy(buf3,de->d_name);
- X if (*buf2)
- X strcat(buf3,"/");
- X strcat(buf3,buf2);
- X strcpy(buf2,buf3);
- X closedir(dir);
- X }
- X}
- X
- X/* open pipes with fds >= 10 */
- X
- Xvoid mpipe(pp) /**/
- Xint *pp;
- X{
- X pipe(pp);
- X pp[0] = movefd(pp[0]);
- X pp[1] = movefd(pp[1]);
- X}
- X
- X/* do process substitution with redirection */
- X
- Xvoid spawnpipes(l) /**/
- XLklist l;
- X{
- XLknode n = firstnode(l);
- XRedir f;
- X
- X for (; n; incnode(n))
- X {
- X f = (Redir) getdata(n);
- X if (f->type == OUTPIPE)
- X {
- X char *str = f->name;
- X f->fd2 = getoutpipe(str);
- X }
- X if (f->type == INPIPE)
- X {
- X char *str = f->name;
- X f->fd2 = getinpipe(str);
- X }
- X }
- X}
- X
- X/* perform time ... command */
- X
- Xint exectime(cmd) /**/
- XCmd cmd;
- X{
- Xint jb = thisjob;
- X
- X if (!cmd->u.pline) { shelltime(); return 0; }
- X execpline(cmd->u.pline,TIMED,0);
- X thisjob = jb;
- X return lastval;
- X}
- X
- X/* define a function */
- X
- Xint execfuncdef(cmd) /**/
- XCmd cmd;
- X{
- XCmdnam cc;
- Xchar *s;
- X
- X permalloc();
- X while (s = ugetnode(cmd->args))
- X {
- X cc = (Cmdnam) zalloc(sizeof *cc);
- X cc->type = SHFUNC;
- X cc->flags = 0;
- X if (!cmd->u.list)
- X cc->u.list = NULL;
- X else
- X cc->u.list = (List) dupstruct(cmd->u.list);
- X addhnode(ztrdup(s),cc,cmdnamtab,freecmdnam);
- X if (!strncmp(s,"TRAP",4))
- X {
- X int t0 = getsignum(s+4);
- X
- X if (t0 != -1)
- X settrap(t0,cmd->u.list);
- X }
- X }
- X heapalloc();
- X return 0;
- X}
- X
- X/* evaluate a [[ ... ]] */
- X
- Xint execcond(cmd) /**/
- XCmd cmd;
- X{
- X return !evalcond(cmd->u.cond);
- X}
- X
- Xvoid execshfunc(cmd,cn) /**/
- XCmd cmd;Cmdnam cn;
- X{
- XList l;
- X
- X if (errflag) return;
- X l = cn->u.list;
- X if (!l) {
- X char *nam;
- X
- X if (!(cn->flags & PMFLAG_u)) return;
- X if (!(l = getfpfunc(nam = peekfirst(cmd->args)))) {
- X zerr("function not found: %s",nam,0);
- X lastval = 1;
- X return;
- X }
- X cn->flags &= ~PMFLAG_u;
- X permalloc();
- X cn->u.list = (List) dupstruct(l);
- X heapalloc();
- X }
- X doshfunc(l,cmd->args,cn->flags);
- X}
- X
- Xvoid doshfuncnoval(list,args,flags) /**/
- XList list; Lklist args; int flags;
- X{
- Xint val = lastval;
- X
- X doshfunc(list,args,flags);
- X lastval = val;
- X}
- X
- Xvoid doshfunc(list,args,flags) /**/
- XList list; Lklist args; int flags;
- X{
- Xchar **tab,**x,*oargv0;
- Xint oxtr = opts[XTRACE],opev = opts[PRINTEXITVALUE],xexittr;
- XLklist olist;
- Xchar *s;
- XList xexitfn;
- X
- X xexittr = sigtrapped[SIGEXIT];
- X xexitfn = sigfuncs[SIGEXIT];
- X tab = pparams;
- X oargv0 = argzero;
- X zoptind = 1;
- X if (flags & PMFLAG_t) opts[XTRACE] = OPT_SET;
- X opts[PRINTEXITVALUE] = OPT_UNSET;
- X if (args) {
- X pparams = x = (char **) zcalloc(((sizeof *x)*(1+countnodes(args))));
- X argzero = ztrdup(ugetnode(args));
- X while (*x = ugetnode(args))
- X *x = ztrdup(*x), x++;
- X } else {
- X pparams = zcalloc(sizeof *pparams);
- X argzero = ztrdup(argzero);
- X }
- X permalloc();
- X olist = locallist;
- X locallist = newlist();
- X heapalloc();
- X runlist(dupstruct(list));
- X while (s = getnode(locallist)) unsetparam(s);
- X free(locallist);
- X locallist = olist;
- X retflag = 0;
- X freearray(pparams);
- X free(argzero);
- X argzero = oargv0;
- X pparams = tab;
- X if (sigfuncs[SIGEXIT] && sigfuncs[SIGEXIT] != xexitfn) {
- X dotrap(SIGEXIT);
- X freestruct(sigfuncs[SIGEXIT]);
- X }
- X sigtrapped[SIGEXIT] = xexittr;
- X sigfuncs[SIGEXIT] = xexitfn;
- X opts[XTRACE] = oxtr;
- X opts[PRINTEXITVALUE] = opev;
- X}
- X
- X/* search fpath for an undefined function */
- X
- XList getfpfunc(s) /**/
- Xchar *s;
- X{
- Xchar **pp = fpath,buf[MAXPATHLEN];
- Xint fd;
- X
- X for (; *pp; pp++)
- X {
- X sprintf(buf,"%s/%s",*pp,s);
- X if (!access(buf,R_OK) && (fd = open(buf,O_RDONLY)) != -1)
- X {
- X int len = lseek(fd,0,2);
- X
- X if (len == -1)
- X close(fd);
- X else
- X {
- X char *d;
- X
- X lseek(fd,0,0);
- X d = zcalloc(len+1);
- X if (read(fd,d,len) != len)
- X {
- X free(d);
- X close(fd);
- X }
- X else
- X {
- X close(fd);
- X return parselstring(d);
- X }
- X }
- X }
- X }
- X return NULL;
- X}
- X
- X/* check to see if AUTOCD applies here */
- X
- Xint cancd(s)
- Xchar *s;
- X{
- Xchar *t;
- X
- X if ((t = getsparam(s)) && *t == '/') return 1;
- X if (*s != '/')
- X {
- X char sbuf[MAXPATHLEN],**cp;
- X
- X if (cancd2(s))
- X return 1;
- X if (access(s,X_OK) == 0)
- X return 0;
- X for (cp = cdpath; *cp; cp++)
- X {
- X sprintf(sbuf,"%s/%s",*cp,s);
- X if (cancd2(sbuf))
- X return 1;
- X }
- X return 0;
- X }
- X return cancd2(s);
- X}
- X
- Xint cancd2(s)
- Xchar *s;
- X{
- Xstruct stat buf;
- X
- X return !(access(s,X_OK) || stat(s,&buf) || !S_ISDIR(buf.st_mode));
- X}
- X
- SHAR_EOF
- echo 'File zsh2.2/src/exec.c is complete' &&
- chmod 0644 zsh2.2/src/exec.c ||
- echo 'restore of zsh2.2/src/exec.c failed'
- Wc_c="`wc -c < 'zsh2.2/src/exec.c'`"
- test 35818 -eq "$Wc_c" ||
- echo 'zsh2.2/src/exec.c: original size 35818, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= zsh2.2/src/funcs.h ==============
- if test -f 'zsh2.2/src/funcs.h' -a X"$1" != X"-c"; then
- echo 'x - skipping zsh2.2/src/funcs.h (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting zsh2.2/src/funcs.h (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/funcs.h' &&
- Xstruct asgment;
- Xstruct utmp;
- X
- X#include "builtin.pro"
- X#include "cond.pro"
- X#include "exec.pro"
- X#include "glob.pro"
- X#include "hist.pro"
- X#include "init.pro"
- X#include "jobs.pro"
- X#include "lex.pro"
- X#include "loop.pro"
- X#include "math.pro"
- X#include "mem.pro"
- X#include "params.pro"
- X#include "parse.pro"
- X#include "subst.pro"
- X#include "table.pro"
- X#include "text.pro"
- X#include "utils.pro"
- X#include "watch.pro"
- X#include "zle_hist.pro"
- X#include "zle_main.pro"
- X#include "zle_misc.pro"
- X#include "zle_move.pro"
- X#include "zle_refresh.pro"
- X#include "zle_tricky.pro"
- X#include "zle_utils.pro"
- X#include "zle_vi.pro"
- X#include "zle_word.pro"
- X
- Xchar *mktemp DCLPROTO((char *));
- X#ifndef HAS_STDLIB
- Xchar *malloc DCLPROTO((int));
- Xchar *realloc DCLPROTO((char *,int));
- Xchar *calloc DCLPROTO((int,int));
- X#endif
- Xchar *ttyname DCLPROTO((int));
- X
- Xextern char PC, *BC, *UP;
- Xextern short ospeed;
- Xextern int tgetent DCLPROTO((char *bp, char *name));
- Xextern int tgetnum DCLPROTO((char *id));
- Xextern int tgetflag DCLPROTO((char *id));
- Xextern char *tgetstr DCLPROTO((char *id, char **area));
- Xextern char *tgoto DCLPROTO((char *cm, int destcol, int destline));
- Xextern int tputs DCLPROTO((char *cp, int affcnt, int (*outc)()));
- SHAR_EOF
- chmod 0644 zsh2.2/src/funcs.h ||
- echo 'restore of zsh2.2/src/funcs.h failed'
- Wc_c="`wc -c < 'zsh2.2/src/funcs.h'`"
- test 1185 -eq "$Wc_c" ||
- echo 'zsh2.2/src/funcs.h: original size 1185, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= zsh2.2/src/glob.c ==============
- if test -f 'zsh2.2/src/glob.c' -a X"$1" != X"-c"; then
- echo 'x - skipping zsh2.2/src/glob.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting zsh2.2/src/glob.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/glob.c' &&
- X/*
- X *
- X * glob.c - filename generation
- X *
- X * This file is part of zsh, the Z shell.
- X *
- X * This software is Copyright 1992 by Paul Falstad
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X *
- X */
- X
- X#include "zsh.h"
- X
- X#ifdef __hpux
- X#include <ndir.h>
- X#else
- X#ifdef SYSV
- X#define direct dirent
- X#else
- X#include <sys/dir.h>
- X#endif
- X#endif
- X#include <sys/errno.h>
- X
- X#define exists(X) (access(X,0) == 0 || readlink(X,NULL,0) == 0)
- X
- Xstatic int mode; /* != 0 if we are parsing glob patterns */
- Xstatic int pathpos; /* position in pathbuf */
- Xstatic int matchsz; /* size of matchbuf */
- Xstatic int matchct; /* number of matches found */
- Xstatic char pathbuf[MAXPATHLEN]; /* pathname buffer */
- Xstatic char **matchbuf; /* array of matches */
- Xstatic char **matchptr; /* &matchbuf[matchct] */
- Xstatic Comp exclude; /* pattern to exclude */
- X
- X/* max # of qualifiers */
- X
- X#define QUALCT 16
- X
- Xstatic int (*qualfuncs[QUALCT])DCLPROTO((struct stat *,long));
- Xstatic long qualdata[QUALCT];
- Xstatic int qualsense[QUALCT];
- Xstatic int qualct;
- Xstatic int gf_nullglob,gf_markdirs,gf_noglobdots;
- X
- X/* pathname component in filename patterns */
- X
- Xstruct complist {
- X Complist next;
- X Comp comp;
- X int closure; /* 1 if this is a (foo/)# */
- X };
- Xstruct comp {
- X Comp left,right,next;
- X char *str;
- X int closure,last;
- X };
- X
- Xvoid glob(list,np) /**/
- XLklist list;Lknode *np;
- X{
- XLknode node = prevnode(*np);
- XLknode next = nextnode(*np);
- Xint sl; /* length of the pattern */
- Xchar *ostr; /* the pattern before the parser chops it up */
- XComplist q; /* pattern after parsing */
- Xchar *str = getdata(*np); /* the pattern */
- X
- X sl = strlen(str);
- X ostr = strdup(str);
- X uremnode(list,*np);
- X qualct = 0;
- X gf_nullglob = isset(NULLGLOB);
- X gf_markdirs = isset(MARKDIRS);
- X gf_noglobdots = unset(GLOBDOTS);
- X if (str[sl-1] == Outpar) /* check for qualifiers */
- X {
- X char *s;
- X int sense = 0;
- X long data;
- X int (*func) DCLPROTO((struct stat *,long));
- X
- X for (s = str+sl-2; s != str; s--)
- X if (*s == Bar || *s == Outpar || *s == Inpar)
- X break;
- X if (*s == Inpar)
- X {
- X *s++ = '\0';
- X func = NULL;
- X while (*s != Outpar)
- X {
- X func = NULL;
- X if (idigit(*s))
- X {
- X func = qualflags;
- X data = 0;
- X while (idigit(*s))
- X data = data*010+(*s++-'0');
- X }
- X else switch ((int)(unsigned char)(*s++))
- X {
- X case (int)(unsigned char)Hat: case '^': sense = 1-sense; break;
- X#ifdef S_IFLNK
- X case '@': func = qualmode; data = S_IFLNK; break;
- X#endif
- X#ifdef S_IFSOCK
- X case '=': func = qualmode; data = S_IFSOCK; break;
- X#endif
- X#ifdef S_IFIFO
- X case 'p': func = qualmode; data = S_IFIFO; break;
- X#endif
- X case '/': func = qualmode; data = S_IFDIR; break;
- X case '.': func = qualmode; data = S_IFREG; break;
- X case '%': func = qualisdev; break;
- X case (int)(unsigned char)Star: func = qualiscom; break;
- X case 'R': func = qualflags; data = 0004; break;
- X case 'W': func = qualflags; data = 0002; break;
- X case 'X': func = qualflags; data = 0001; break;
- X case 'r': func = qualflags; data = 0400; break;
- X case 'w': func = qualflags; data = 0200; break;
- X case 'x': func = qualflags; data = 0100; break;
- X case 's': func = qualflags; data = 04000; break;
- X case 'S': func = qualflags; data = 02000; break;
- X case 'd': func = qualdev; data = qgetnum(&s); break;
- X case 'l': func = qualnlink; data = qgetnum(&s); break;
- X case 'U': func = qualuid; data = geteuid(); break;
- X case 'G': func = qualgid; data = getegid(); break;
- X case 'u': func = qualuid; data = qgetnum(&s); break;
- X case 'g': func = qualgid; data = qgetnum(&s); break;
- X case 'M': gf_markdirs = !sense; break;
- X case 'N': gf_nullglob = !sense; break;
- X case 'D': gf_noglobdots = sense; break;
- X default: zerr("unknown file attribute",NULL,0); return;
- X }
- X if (func)
- X {
- X if (qualct == QUALCT-1)
- X {
- X zerr("too many qualifiers",NULL,0);
- X return;
- X }
- X qualfuncs[qualct] = func;
- X qualsense[qualct] = sense;
- X qualdata[qualct] = data;
- X qualct++;
- X }
- X if (errflag)
- X return;
- X }
- X }
- X }
- X else if ((str[sl-1] == '/') && !((str[sl-2] == Star)&&
- X (str[sl-3] == Star)&&(str[sl-4] == Star)&&
- X (str[sl-5]==Star))) /* foo/ == foo(/) */
- X {
- X str[sl-1] = '\0';
- X qualfuncs[0] = qualmode;
- X qualdata[0] = S_IFDIR;
- X qualsense[0] = 0;
- X qualct = 1;
- X }
- X qualfuncs[qualct] = NULL;
- X if (*str == '/') /* pattern has absolute path */
- X {
- X str++;
- X pathbuf[0] = '/';
- X pathbuf[pathpos = 1] = '\0';
- X }
- X else /* pattern is relative to pwd */
- X pathbuf[pathpos = 0] = '\0';
- X q = parsepat(str);
- X if (!q || errflag) /* if parsing failed */
- X {
- X if (isset(NOBADPATTERN))
- X {
- X insnode(list,node,ostr);
- X return;
- X }
- X errflag = 0;
- X zerr("bad pattern: %s",ostr,0);
- X return;
- X }
- X matchptr = matchbuf = (char **) zalloc((matchsz = 16)*sizeof(char *));
- X matchct = 0;
- X scanner(q); /* do the globbing */
- X if (matchct)
- X badcshglob |= 2;
- X else if (!gf_nullglob)
- X if (isset(CSHNULLGLOB)) {
- X badcshglob |= 1;
- X } else if (unset(NONOMATCH)) {
- X zerr("no matches found: %s",ostr,0);
- X free(matchbuf);
- X return;
- X } else {
- X *matchptr++ = strdup(ostr);
- X matchct = 1;
- X }
- X qsort(&matchbuf[0],matchct,sizeof(char *),notstrcmp);
- X matchptr = matchbuf;
- X while (matchct--) /* insert matches in the arg list */
- X insnode(list,node,*matchptr++);
- X free(matchbuf);
- X *np = (next) ? prevnode(next) : lastnode(list);
- X}
- X
- X/* get number after qualifier */
- X
- Xlong qgetnum(s) /**/
- Xchar **s;
- X{
- Xlong v = 0;
- X
- X if (!idigit(**s))
- X {
- X zerr("number expected",NULL,0);
- X return 0;
- X }
- X while (idigit(**s))
- X v = v*10+*(*s)++-'0';
- X return v;
- X}
- X
- Xint notstrcmp(a,b) /**/
- Xchar **a;char **b;
- X{
- Xchar *c = *b,*d = *a;
- Xint x1,x2;
- X
- X for (; *c == *d && *c; c++,d++);
- X x1 = atoi(c); x2 = atoi(d);
- X if (x1==x2 || unset(NUMERICGLOBSORT))
- X return ((int) (unsigned char) *c-(int) (unsigned char) *d);
- X return x1-x2;
- X}
- X
- Xint forstrcmp(a,b) /**/
- Xchar **a;char **b;
- X{
- Xchar *c = *b,*d = *a;
- X
- X for (; *c == *d && *c; c++,d++);
- X return ((int) (unsigned char) *d-(int) (unsigned char) *c);
- X}
- X
- X/* add a match to the list */
- X
- Xvoid insert(s) /**/
- Xchar *s;
- X{
- Xstruct stat buf;
- Xint statted = 0;
- X
- X if (exclude && domatch(s,exclude,gf_noglobdots)) return;
- X if (gf_markdirs && !lstat(s,&buf) && S_ISDIR(buf.st_mode)) {
- X char *t;
- X int ll = strlen(s);
- X
- X t = ncalloc(ll+2);
- X strcpy(t,s);
- X t[ll] = '/';
- X t[ll+1] = '\0';
- X s = t;
- X statted = 1;
- X }
- X if (qualct) { /* do the (X) (^X) stuff */
- X int (**fptr)DCLPROTO((struct stat *,long)) = qualfuncs;
- X int *sptr = qualsense;
- X long *lptr = qualdata;
- X struct stat buf;
- X
- X if (statted || lstat(s,&buf) >= 0)
- X while (*fptr) if (!(!!((*fptr++)(&buf,*lptr++)) ^ *sptr++)) return;
- X }
- X *matchptr++ = s;
- X if (++matchct == matchsz) {
- X matchbuf = (char **) realloc((char *) matchbuf,
- X sizeof(char **)*(matchsz *= 2));
- X matchptr = matchbuf+matchct;
- X }
- X}
- X
- X/* check to see if str is eligible for filename generation */
- X
- Xint haswilds(str) /**/
- Xchar *str;
- X{
- X if ((*str == Inbrack || *str == Outbrack) && !str[1]) return 0;
- X if (str[0] == '%') return 0;
- X for (; *str; str++)
- X if (*str == Pound || *str == Hat || *str == Star ||
- X *str == Bar || *str == Inbrack || *str == Inang ||
- X *str == Quest) return 1;
- X return 0;
- X}
- X
- X/* check to see if str is eligible for brace expansion */
- X
- Xint hasbraces(str) /**/
- Xchar *str;
- X{
- Xint mb,bc,cmct1,cmct2;
- Xchar *lbr = NULL;
- X
- X if (str[0] == Inbrace && str[1] == Outbrace)
- X return 0;
- X if (isset(BRACECCL)) {
- X for (mb = bc = 0; *str; ++str)
- X if (*str == Inbrace) {
- X if (++bc > mb)
- X mb = bc;
- X }
- X else if (*str == Outbrace)
- X if (--bc < 0)
- X return(0);
- X return(mb && bc == 0);
- X }
- X for (mb = bc = cmct1 = cmct2 = 0; *str; str++)
- X {
- X if (*str == Inbrace)
- X {
- X if (!bc)
- X lbr = str;
- X bc++;
- X if (str[4] == Outbrace && str[2] == '-') /* {a-z} */
- X {
- X cmct1++;
- X if (bc == 1)
- X cmct2++;
- X }
- X }
- X else if (*str == Outbrace)
- X {
- X bc--;
- X if (!bc)
- X {
- X if (!cmct2)
- X {
- X *lbr = '{';
- X *str = '}';
- X }
- X cmct2 = 0;
- X }
- X }
- X else if (*str == Comma && bc)
- X {
- X cmct1++;
- X if (bc == 1)
- X cmct2++;
- X }
- X if (bc > mb)
- X mb = bc;
- X if (bc < 0)
- X return 0;
- X }
- X return (mb && bc == 0 && cmct1);
- X}
- X
- X/* expand stuff like >>*.c */
- X
- Xint xpandredir(fn,tab) /**/
- Xstruct redir *fn;Lklist tab;
- X{
- XLklist fake;
- Xchar *nam;
- Xstruct redir *ff;
- Xint ret = 0;
- X
- X fake = newlist();
- X addnode(fake,fn->name);
- X prefork(fake);
- X if (!errflag)
- X postfork(fake,1);
- X if (errflag) return 0;
- X if (full(fake) && !nextnode(firstnode(fake))) {
- X fn->name = peekfirst(fake);
- X untokenize(fn->name);
- X } else
- X while (nam = ugetnode(fake)) {
- X ff = alloc(sizeof *ff);
- X *ff = *fn;
- X ff->name = nam;
- X addnode(tab,ff);
- X ret = 1;
- X }
- X return ret;
- X}
- X
- X/* concatenate s1 and s2 in dynamically allocated buffer */
- X
- Xchar *dyncat(s1,s2) /**/
- Xchar *s1;char *s2;
- X{
- Xchar *ptr;
- X
- X ptr = ncalloc(strlen(s1)+strlen(s2)+1);
- X strcpy(ptr,s1);
- X strcat(ptr,s2);
- X return ptr;
- X}
- X
- X/* concatenate s1, s2, and s3 in dynamically allocated buffer */
- X
- Xchar *tricat(s1,s2,s3) /**/
- Xchar *s1;char *s2;char *s3;
- X{
- Xchar *ptr;
- X
- X ptr = zalloc(strlen(s1)+strlen(s2)+strlen(s3)+1);
- X strcpy(ptr,s1);
- X strcat(ptr,s2);
- X strcat(ptr,s3);
- X return ptr;
- X}
- X
- X/* brace expansion */
- X
- Xvoid xpandbraces(list,np) /**/
- XLklist list;Lknode *np;
- X{
- XLknode node = (*np),last = prevnode(node);
- Xchar *str = getdata(node),*str3 = str,*str2;
- Xint prev, bc, comma;
- X
- X for (; *str != Inbrace; str++);
- X for (str2 = str, bc = comma = 0; *str2; ++str2)
- X if (*str2 == Inbrace)
- X ++bc;
- X else if (*str2 == Outbrace) {
- X if (--bc == 0)
- X break;
- X }
- X else if (bc == 1 && *str2 == Comma)
- X ++comma;
- X if (!comma && !bc && isset(BRACECCL)) { /* {a-mnop} */
- X char ccl[256], *p;
- X unsigned char c1,c2,lastch;
- X
- X uremnode(list,node);
- X memset(ccl, 0, sizeof(ccl) / sizeof(ccl[0]));
- X for (p = str + 1, lastch = 0; p < str2; ) {
- X if (itok(c1 = *p++))
- X c1 = ztokens[c1 - (unsigned char)Pound];
- X if (itok(c2 = *p))
- X c2 = ztokens[c2 - (unsigned char)Pound];
- X if (c1 == '-' && lastch && p < str2 && lastch <= c2) {
- X while (lastch < c2)
- X ccl[lastch++] = 1;
- X lastch = 0;
- X }
- X else
- X ccl[lastch = c1] = 1;
- X }
- X strcpy(str + 1, str2 + 1);
- X for (p = ccl+255; p-- > ccl; )
- X if (*p) {
- X *str = p - ccl;
- X insnode(list, last, strdup(str3));
- X }
- X *np = nextnode(last);
- X return;
- X }
- X if (str[2] == '-' && str[4] == Outbrace) /* {a-z} */
- X {
- X char c1,c2;
- X
- X uremnode(list,node);
- X chuck(str);
- X c1 = *str;
- X chuck(str);
- X chuck(str);
- X c2 = *str;
- X chuck(str);
- X if (itok(c1))
- X c1 = ztokens[c1-Pound];
- X if (itok(c2))
- X c2 = ztokens[c2-Pound];
- X if (c1 < c2)
- X for (; c2 >= c1; c2--) /* {a-z} */
- X {
- X *str = c2;
- X insnode(list,last,strdup(str3));
- X }
- X else
- X for (; c2 <= c1; c2++) /* {z-a} */
- X {
- X *str = c2;
- X insnode(list,last,strdup(str3));
- X }
- X *np = nextnode(last);
- X return;
- X }
- X prev = str-str3;
- X str2 = getparen(str++);
- X if (!str2)
- X {
- X zerr("how did you get this error?",NULL,0);
- X return;
- X }
- X uremnode(list,node);
- X node = last;
- X for(;;)
- X {
- X char *zz,*str4;
- X int cnt;
- X
- X for (str4 = str, cnt = 0; cnt || *str != Comma && *str !=
- X Outbrace; str++)
- X if (*str == Inbrace)
- X cnt++;
- X else if (*str == Outbrace)
- X cnt--;
- X else if (!*str)
- X exit(10);
- X zz = zalloc(prev+(str-str4)+strlen(str2)+1);
- X ztrncpy(zz,str3,prev);
- X strncat(zz,str4,str-str4);
- X strcat(zz,str2);
- X insnode(list,node,zz);
- X incnode(node);
- X if (*str != Outbrace)
- X str++;
- X else
- X break;
- X }
- X *np = nextnode(last);
- X}
- X
- X/* get closing paren, given pointer to opening paren */
- X
- Xchar *getparen(str) /**/
- Xchar *str;
- X{
- Xint cnt = 1;
- Xchar typein = *str++,typeout = typein+1;
- X
- X for (; *str && cnt; str++)
- X if (*str == typein)
- X cnt++;
- X else if (*str == typeout)
- X cnt--;
- X if (!str && cnt)
- X return NULL;
- X return str;
- X}
- X
- X/* check to see if a matches b (b is not a filename pattern) */
- X
- Xint matchpat(a,b) /**/
- Xchar *a;char *b;
- X{
- XComp c;
- Xint val,len;
- Xchar *b2;
- X
- X remnulargs(b);
- X len = strlen(b);
- X b2 = alloc(len+3);
- X strcpy(b2+1,b);
- X b2[0] = Inpar;
- X b2[len+1] = Outpar;
- X b2[len+2] = '\0';
- X c = parsereg(b2);
- X if (!c)
- X {
- X zerr("bad pattern: %s",b,0);
- X return 0;
- X }
- X val = domatch(a,c,0);
- X return val;
- X}
- X
- X/* do the ${foo%%bar}, ${foo#bar} stuff */
- X/* please do not laugh at this code. */
- X
- Xvoid getmatch(sp,pat,dd) /**/
- Xchar **sp;char *pat;int dd;
- X{
- XComp c;
- Xchar *t,*lng = NULL,cc,*s = *sp;
- X
- X remnulargs(pat);
- X c = parsereg(pat);
- X if (!c)
- X {
- X zerr("bad pattern: %s",pat,0);
- X return;
- X }
- X if (!(dd & 2))
- X {
- X for (t = s; t==s || t[-1]; t++)
- X {
- X cc = *t;
- X *t = '\0';
- X if (domatch(s,c,0))
- X {
- X if (!(dd & 1))
- X {
- X *t = cc;
- X t = strdup(t);
- X *sp = t;
- X return;
- X }
- X lng = t;
- X }
- X *t = cc;
- X }
- X if (lng)
- X {
- X t = strdup(lng);
- X *sp = t;
- X return;
- X }
- X }
- X else
- X {
- X for (t = s+strlen(s); t >= s; t--)
- X {
- X if (domatch(t,c,0))
- X {
- X if (!(dd & 1))
- X {
- X cc = *t;
- X *t = '\0';
- X *sp = strdup(*sp);
- X *t = cc;
- X return;
- X }
- X lng = t;
- X }
- X }
- X if (lng)
- X {
- X cc = *lng;
- X *lng = '\0';
- X *sp = strdup(*sp);
- X *lng = cc;
- X return;
- X }
- X }
- X}
- X
- X/* add a component to pathbuf */
- X
- Xstatic int addpath(s)
- Xchar *s;
- X{
- X if (strlen(s)+pathpos >= MAXPATHLEN) return 0;
- X while (pathbuf[pathpos++] = *s++);
- X pathbuf[pathpos-1] = '/';
- X pathbuf[pathpos] = '\0';
- X return 1;
- X}
- X
- Xchar *getfullpath(s) /**/
- Xchar *s;
- X{
- Xstatic char buf[MAXPATHLEN];
- X
- X strcpy(buf,pathbuf);
- X strcat(buf,s);
- X return buf;
- X}
- X
- X/* do the globbing */
- X
- Xvoid scanner(q) /**/
- XComplist q;
- X{
- XComp c;
- Xint closure;
- X
- X if (closure = q->closure) /* (foo/)# */
- X if (q->closure == 2) /* (foo/)## */
- X q->closure = 1;
- X else
- X scanner(q->next);
- X if (c = q->comp)
- X {
- X if (!(c->next || c->left) && !haswilds(c->str))
- X if (q->next)
- X {
- X int oppos = pathpos;
- X
- X if (errflag)
- X return;
- X if (q->closure && !strcmp(c->str,".")) return;
- X if (!addpath(c->str)) return;
- X if (!closure || exists(pathbuf))
- X scanner((q->closure) ? q : q->next);
- X pathbuf[pathpos = oppos] = '\0';
- X }
- X else
- X {
- X char *s;
- X
- X if (exists(s = getfullpath(c->str)))
- X insert(strdup(s));
- X }
- X else
- X {
- X char *fn;
- X int dirs = !!q->next;
- X struct direct *de;
- X DIR *lock = opendir((*pathbuf) ? pathbuf : ".");
- X
- X if (lock == NULL)
- X return;
- X readdir(lock); readdir(lock); /* skip . and .. */
- X while (de = readdir(lock))
- X {
- X if (errflag)
- X break;
- X fn = &de->d_name[0];
- X if (domatch(fn,c,gf_noglobdots))
- X {
- X int oppos = pathpos;
- X
- X if (dirs)
- X {
- X if (closure)
- X {
- X int type3;
- X struct stat buf;
- X
- X if (lstat(getfullpath(fn),&buf) == -1)
- X {
- X if (errno != ENOENT && errno != EINTR &&
- X errno != ENOTDIR)
- X {
- X zerr("%e: %s",fn,errno);
- X errflag = 0;
- X }
- X continue;
- X }
- X type3 = buf.st_mode & S_IFMT;
- X if (type3 != S_IFDIR)
- X continue;
- X }
- X if (addpath(fn))
- X scanner((q->closure) ? q : q->next); /* scan next level */
- X pathbuf[pathpos = oppos] = '\0';
- X }
- X else insert(dyncat(pathbuf,fn));
- X }
- X }
- X closedir(lock);
- X }
- X }
- X else
- X zerr("no idea how you got this error message.",NULL,0);
- X}
- X
- X/* do the [..(foo)..] business */
- X
- Xint minimatch(pat,str) /**/
- Xchar **pat;char **str;
- X{
- Xchar *pt = *pat+1,*s = *str;
- X
- X for (; *pt != Outpar; s++,pt++)
- X if ((*pt != Quest || !*s) && *pt != *s)
- X {
- X *pat = getparen(*pat)-1;
- X return 0;
- X }
- X *str = s-1;
- X return 1;
- X}
- X
- Xstatic char *pptr;
- Xstatic Comp tail = 0;
- Xstatic int first;
- X
- Xint domatch(str,c,fist) /**/
- Xchar *str;Comp c;int fist;
- X{
- X pptr = str;
- X first = fist;
- X return doesmatch(c);
- X}
- X
- X/* see if current pattern matches c */
- X
- Xint doesmatch(c) /**/
- XComp c;
- X{
- Xchar *pat = c->str;
- X
- X if (c->closure == 1) {
- X char *saves = pptr;
- X
- X if (first && *pptr == '.') return 0;
- X if (doesmatch(c->next)) return 1;
- X pptr = saves;
- X first = 0;
- X }
- X for(;;)
- X {
- X if (!pat || !*pat)
- X {
- X char *saves;
- X int savei;
- X
- X if (errflag)
- X return 0;
- X saves = pptr;
- X savei = first;
- X if (c->left || c->right)
- X if (!doesmatch(c->left))
- X if (c->right)
- X {
- X pptr = saves;
- X first = savei;
- X if (!doesmatch(c->right))
- X return 0;
- X }
- X else
- X return 0;
- X if (c->closure)
- X return doesmatch(c);
- X if (!c->next)
- X return (!c->last || !*pptr);
- X return doesmatch(c->next);
- X }
- X if (first && *pptr == '.' && *pat != '.')
- X return 0;
- X if (*pat == Star) /* final * is not expanded to ?#; returns success */
- X {
- X while (*pptr) pptr++;
- X return 1;
- X }
- X first = 0;
- X if (*pat == Quest && *pptr)
- X {
- X pptr++;
- X pat++;
- X continue;
- X }
- X if (*pat == Hat)
- X return 1-doesmatch(c->next);
- X if (*pat == Inbrack) {
- X if (!*pptr) break;
- X if (pat[1] == Hat || pat[1] == '^') {
- X pat[1] = Hat;
- X for (pat += 2; *pat != Outbrack && *pat; pat++)
- X if (*pat == '-' && pat[-1] != Hat && pat[1] != Outbrack) {
- X if (pat[-1] <= *pptr && pat[1] >= *pptr)
- X break;
- X } else if (*pptr == *pat) break;
- X if (!*pat) {
- X zerr("something is very wrong.",NULL,0);
- X return 0;
- X }
- X if (*pat != Outbrack)
- X break;
- X pat++;
- X pptr++;
- X continue;
- X } else {
- X for (pat++; *pat != Outbrack && *pat; pat++)
- X if (*pat == Inpar) {
- X if (minimatch(&pat,&pptr))
- X break;
- X } else if (*pat == '-' && pat[-1] != Inbrack &&
- X pat[1] != Outbrack) {
- X if (pat[-1] <= *pptr && pat[1] >= *pptr)
- X break;
- X } else if (*pptr == *pat) break;
- X if (!pat || !*pat) {
- X zerr("oh dear. that CAN'T be right.",NULL,0);
- X return 0;
- X }
- X if (*pat == Outbrack)
- X break;
- X for (pptr++; *pat != Outbrack; pat++);
- X pat++;
- X continue;
- X }
- X }
- X if (*pat == Inang)
- X {
- X int t1,t2,t3;
- X char *ptr;
- X
- X if (*++pat == Outang) /* handle <> case */
- X {
- X ( void ) zstrtol(pptr,&ptr,10);
- X if (ptr == pptr)
- X break;
- X pptr = ptr;
- X pat++;
- X }
- X else
- X {
- X t1 = zstrtol(pptr,&ptr,10);
- X if (ptr == pptr)
- X break;
- X pptr = ptr;
- X t2 = zstrtol(pat,&ptr,10);
- X if (*ptr != '-')
- X exit(31);
- X t3 = zstrtol(ptr+1,&pat,10);
- X if (!t3)
- X t3 = -1;
- X if (*pat++ != Outang)
- X exit(21);
- X if (t1 < t2 || (t3 != -1 && t1 > t3))
- X break;
- X }
- X continue;
- X }
- X if (*pptr == *pat)
- X {
- X pptr++;
- X pat++;
- X continue;
- X }
- X break;
- X }
- X return 0;
- X}
- X
- XComplist parsepat(str) /**/
- Xchar *str;
- X{
- Xchar *s;
- X
- X exclude = NULL;
- X if (isset(EXTENDEDGLOB)) {
- X s = str+strlen(str);
- X while (s-- > str) {
- X if (*s == Tilde && s[1]) {
- X *s++ = '\0';
- X exclude = parsereg(s);
- X if (!exclude) return NULL;
- X break;
- X }
- X }
- X }
- X mode = 0;
- X pptr = str;
- X return parsecomplist();
- X}
- X
- XComp parsereg(str) /**/
- Xchar *str;
- X{
- X mode = 1;
- X pptr = str;
- X return parsecompsw();
- X}
- X
- XComplist parsecomplist() /**/
- X{
- XComp c1;
- XComplist p1;
- X
- X if (pptr[0] == Star && pptr[1] == Star &&
- X (pptr[2] == '/' ||
- X (pptr[2] == Star && pptr[3] == Star && pptr[4] == '/'))) {
- X pptr += 3;
- X if (pptr[-1] == Star) pptr += 2;
- X p1 = (Complist) alloc(sizeof *p1);
- X p1->next = parsecomplist();
- X p1->comp = (Comp) alloc(sizeof *p1->comp);
- X p1->comp->last = 1;
- X p1->comp->str = strdup("*");
- X *p1->comp->str = Star;
- X p1->closure = 1;
- X return p1;
- X }
- X if (*pptr == Inpar)
- X {
- X char *str;
- X int pars = 1;
- X
- X for (str = pptr+1; *str && pars; str++)
- X if (*str == Inpar)
- X pars++;
- X else if (*str == Outpar)
- X pars--;
- X if (str[0] != Pound || str[-1] != Outpar || str[-2] != '/')
- X goto kludge;
- X pptr++;
- X if (!(c1 = parsecompsw()))
- X return NULL;
- X if (pptr[0] == '/' && pptr[1] == Outpar && pptr[2] == Pound)
- X {
- X int pdflag = 0;
- X
- X pptr += 3;
- X if (*pptr == Pound)
- X {
- X pdflag = 1;
- X pptr++;
- X }
- X p1 = (Complist) alloc(sizeof *p1);
- X p1->comp = c1;
- X p1->closure = 1+pdflag;
- X p1->next = parsecomplist();
- X return (p1->comp) ? p1 : NULL;
- X }
- X }
- X else
- X {
- Xkludge:
- X if (!(c1 = parsecompsw()))
- X return NULL;
- X if (*pptr == '/' || !*pptr)
- X {
- X int ef = *pptr == '/';
- X
- X p1 = (Complist) alloc(sizeof *p1);
- X p1->comp = c1;
- X p1->closure = 0;
- X p1->next = (*pptr == '/') ? (pptr++,parsecomplist()) : NULL;
- X return (ef && !p1->next) ? NULL : p1;
- X }
- X }
- X errflag = 1;
- X return NULL;
- X}
- X
- XComp parsecomp() /**/
- X{
- XComp c = (Comp) alloc(sizeof *c),c1,c2;
- Xchar *s = c->str = alloc(MAXPATHLEN*2),*ls = NULL;
- X
- X c->next = tail;
- X
- X while (*pptr && (mode || *pptr != '/') && *pptr != Bar &&
- X *pptr != Outpar)
- X {
- X if (*pptr == Hat)
- X {
- X *s++ = Hat;
- X *s++ = '\0';
- X pptr++;
- X if (!(c->next = parsecomp()))
- X return NULL;
- X return c;
- X }
- X if (*pptr == Star && pptr[1] && (mode || pptr[1] != '/'))
- X {
- X *s++ = '\0';
- X pptr++;
- X c1 = (Comp) alloc(sizeof *c1);
- X *(c1->str = strdup("?")) = Quest;
- X c1->closure = 1;
- X if (!(c2 = parsecomp())) return NULL;
- X c1->next = c2;
- X c->next = c1;
- X return c;
- X }
- X if (*pptr == Inpar)
- X {
- X int pars = 1;
- X char *startp = pptr, *endp;
- X Comp stail = tail;
- X int dpnd = 0;
- X
- X for (pptr = pptr+1; *pptr && pars; pptr++)
- X if (*pptr == Inpar)
- X pars++;
- X else if (*pptr == Outpar)
- X pars--;
- X if (pptr[-1] != Outpar)
- X {
- X errflag = 1;
- X return NULL;
- X }
- X if (*pptr == Pound)
- X {
- X dpnd = 1;
- X pptr++;
- X if (*pptr == Pound)
- X {
- X pptr++;
- X dpnd = 2;
- X }
- X }
- X if (!(c1 = parsecomp())) return NULL;
- X tail = c1;
- X endp = pptr;
- X pptr = startp;
- X pptr++;
- X *s++ = '\0';
- X c->next = (Comp) alloc(sizeof *c);
- X c->next->left = parsecompsw();
- X c->next->closure = dpnd;
- X c->next->next = (Comp) alloc(sizeof *c);
- X pptr = endp;
- X tail = stail;
- X return c;
- X }
- X if (*pptr == Pound)
- X {
- X *s = '\0';
- X pptr++;
- X if (!ls)
- X return NULL;
- X if (*pptr == Pound)
- X {
- X pptr++;
- X c->next = c1 = (Comp) alloc(sizeof *c);
- X c1->str = strdup(ls);
- X }
- X else
- X c1 = c;
- X c1->next = c2 = (Comp) alloc(sizeof *c);
- X c2->str = strdup(ls);
- X c2->closure = 1;
- X c2->next = parsecomp();
- X if (!c2->next)
- X return NULL;
- X *ls++ = '\0';
- X return c;
- X }
- X ls = s;
- X if (*pptr == Inang)
- X {
- X int dshct;
- X
- X dshct = (pptr[1] == Outang);
- X *s++ = *pptr++;
- X while (*pptr && (*s++ = *pptr++) != Outang)
- X if (s[-1] == '-')
- X dshct++;
- X else if (!idigit(s[-1]))
- X break;
- X if (s[-1] != Outang || dshct != 1)
- X return NULL;
- X }
- X else if (*pptr == Inbrack)
- X {
- X while (*pptr && (*s++ = *pptr++) != Outbrack);
- X if (s[-1] != Outbrack)
- X return NULL;
- X }
- X else if (itok(*pptr) && *pptr != Star && *pptr != Quest)
- X *s++ = ztokens[*pptr++-Pound];
- X else
- X *s++ = *pptr++;
- X }
- X if (*pptr == '/' || !*pptr)
- X c->last = 1;
- X *s++ = '\0';
- X return c;
- X}
- X
- XComp parsecompsw() /**/
- X{
- XComp c1,c2,c3;
- X
- X c1 = parsecomp();
- X if (!c1)
- X return NULL;
- X if (*pptr == Bar)
- X {
- X c2 = (Comp) alloc(sizeof *c2);
- X pptr++;
- X c3 = parsecompsw();
- X if (!c3)
- X return NULL;
- X c2->str = strdup("");
- X c2->left = c1;
- X c2->right = c3;
- X return c2;
- X }
- X return c1;
- X}
- X
- X/* tokenize and see if ss matches tt */
- X
- Xint patmatch(ss,tt) /**/
- Xchar *ss;char *tt;
- X{
- Xchar *s = ss,*t;
- X
- X for (; *s; s++)
- X if (*s == '\\')
- X chuck(s);
- X else
- X for (t = ztokens; *t; t++)
- X if (*t == *s)
- X {
- X *s = (t-ztokens)+Pound;
- X break;
- X }
- X return matchpat(ss,tt);
- X}
- X
- X/* remove unnecessary Nulargs */
- X
- Xvoid remnulargs(s) /**/
- Xchar *s;
- X{
- Xint nl = *s;
- Xchar *t = s;
- X
- X while (*s)
- X if (*s == Nularg)
- X chuck(s);
- X else
- X s++;
- X if (!*t && nl)
- X {
- X t[0] = Nularg;
- X t[1] = '\0';
- X }
- X}
- X
- X/* qualifier functions */
- X
- Xint qualdev(buf,dv) /**/
- Xstruct stat *buf;long dv;
- X{
- X return buf->st_dev == dv;
- X}
- X
- Xint qualnlink(buf,ct) /**/
- Xstruct stat *buf;long ct;
- X{
- X return buf->st_nlink == ct;
- X}
- X
- Xint qualuid(buf,uid) /**/
- Xstruct stat *buf;long uid;
- X{
- X return buf->st_uid == uid;
- X}
- X
- Xint qualgid(buf,gid) /**/
- Xstruct stat *buf;long gid;
- X{
- X return buf->st_gid == gid;
- X}
- X
- Xint qualisdev(buf,junk) /**/
- Xstruct stat *buf;long junk;
- X{
- X junk = buf->st_mode & S_IFMT;
- X return junk == S_IFBLK || junk == S_IFCHR;
- X}
- X
- Xint qualmode(buf,mod) /**/
- Xstruct stat *buf;long mod;
- X{
- X return (buf->st_mode & S_IFMT) == mod;
- X}
- X
- Xint qualflags(buf,mod) /**/
- Xstruct stat *buf;long mod;
- X{
- X return buf->st_mode & mod;
- X}
- X
- Xint qualiscom(buf,mod) /**/
- Xstruct stat *buf;long mod;
- X{
- X return (buf->st_mode & (S_IFMT|S_IEXEC)) == (S_IFREG|S_IEXEC);
- X}
- X
- SHAR_EOF
- chmod 0644 zsh2.2/src/glob.c ||
- echo 'restore of zsh2.2/src/glob.c failed'
- Wc_c="`wc -c < 'zsh2.2/src/glob.c'`"
- test 24554 -eq "$Wc_c" ||
- echo 'zsh2.2/src/glob.c: original size 24554, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= zsh2.2/src/hist.c ==============
- if test -f 'zsh2.2/src/hist.c' -a X"$1" != X"-c"; then
- echo 'x - skipping zsh2.2/src/hist.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting zsh2.2/src/hist.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'zsh2.2/src/hist.c' &&
- X/*
- X *
- X * hist.c - history expansion
- X *
- X * This file is part of zsh, the Z shell.
- X *
- X * This software is Copyright 1992 by Paul Falstad
- X *
- X * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- X * use this software as long as: there is no monetary profit gained
- X * specifically from the use or reproduction of this software, it is not
- X * sold, rented, traded or otherwise marketed, and this copyright notice is
- X * included prominently in any copy made.
- X *
- X * The author make no claims as to the fitness or correctness of this software
- X * for any use whatsoever, and it is provided as is. Any use of this software
- X * is at the user's own risk.
- X *
- X */
- X
- X#include "zsh.h"
- X
- X#define HEAPSIZE 4096
- X
- Xstruct hp {
- X Hp next;
- X char *pool,*ptr;
- X int free,histno;
- X};
- X
- Xstatic Hp hp_lit, hp_lex;
- Xstatic Histent curhistent;
- X
- Xstatic int lastc;
- X
- X/* add a character to the current history word */
- X
- Xvoid hwaddc(c) /**/
- Xint c;
- X{
- X if (hlastw && hline && (!(errflag || lexstop) || c == HISTSPACE)) {
- X if (c == '!' && unset(NOBANGHIST)) hwaddc('\\');
- X *hptr++ = c;
- X if (hptr-hline >= hlinesz) {
- X int ll,flag = 0,oldsiz = hlinesz;
- X
- X ll = hptr-hlastw;
- X if (curhistent->lex == hline) flag = 1;
- X hline = hp_realloc(&hp_lex,hline,oldsiz,hlinesz = oldsiz+16);
- X if (flag) curhistent->lex = hline;
- X hptr = hline+oldsiz;
- X hlastw = hptr-ll;
- X }
- X }
- X}
- X
- X#define habort() { errflag = lexstop = 1; return ' '; }
- X
- X/* get a character after performing history substitution */
- X
- Xint hgetc() /**/
- X{
- Xint c,ev,farg,larg,argc,marg = -1,cflag = 0,bflag = 0;
- Xchar buf[256],*ptr;
- Xchar *sline,*eline;
- X
- Xtailrec:
- X c = hgetch();
- X if (stophist || alstackind)
- X {
- X hwaddc(c);
- X return c;
- X }
- X if (isfirstch && c == hatchar)
- X {
- X isfirstch = 0;
- X hungetch(hatchar);
- X hungets(":s");
- X c = bangchar;
- X goto hatskip;
- X }
- X if (c != ' ')
- X isfirstch = 0;
- X if (c == '\\') {
- X int g = hgetch();
- X
- X if (g != bangchar)
- X hungetch(g);
- X else {
- X hwaddc(bangchar);
- X return bangchar;
- X }
- X }
- X if (c != bangchar)
- X {
- X hwaddc(c);
- X return c;
- X }
- Xhatskip:
- X *hptr = '\0';
- X if ((c = hgetch()) == '{')
- X {
- X bflag = cflag = 1;
- X c = hgetch();
- X }
- X if (c == '\"')
- X {
- X stophist = 1;
- X goto tailrec;
- X }
- X if (!cflag && inblank(c) || c == '=' || c == '(' || lexstop)
- X {
- X if (lexstop)
- X lexstop = 0;
- X else
- X hungetch(c);
- X hwaddc(bangchar);
- X return bangchar;
- X }
- X cflag = 0;
- X ptr = buf;
- X
- X /* get event number */
- X
- X if (c == '?')
- X {
- X for(;;)
- X {
- X c = hgetch();
- X if (c == '?' || c == '\n' || lexstop)
- X break;
- X else
- X *ptr++ = c;
- X }
- X if (c != '\n' && !lexstop)
- X c = hgetch();
- X *ptr = '\0';
- X ev = hconsearch(hsubl = ztrdup(buf),&marg);
- X if (ev == -1)
- X {
- X herrflush();
- X zerr("no such event: %s",buf,0);
- X habort();
- X }
- X }
- X else
- X {
- X int t0;
- X
- X for (;;)
- X {
- X if (inblank(c) || c == ';' || c == ':' || c == '^' || c == '$' ||
- X c == '*' || c == '%' || c == '}' || lexstop)
- X break;
- X if (ptr != buf) {
- X if (c == '-') break;
- X if ((idigit(buf[0]) || buf[0] == '-') && !idigit(c)) break;
- X }
- X *ptr++ = c;
- X if (c == '#' || c == bangchar)
- X {
- X c = hgetch();
- X break;
- X }
- X c = hgetch();
- X }
- X *ptr = 0;
- X if (!*buf)
- X ev = defev;
- X else if (t0 = atoi(buf))
- X ev = (t0 < 0) ? curhist+t0 : t0;
- X else if (*buf == bangchar)
- X ev = curhist-1;
- X else if (*buf == '#')
- X ev = curhist;
- X else if ((ev = hcomsearch(buf)) == -1)
- X {
- X zerr("event not found: %s",buf,0);
- X while (c != '\n' && !lexstop)
- X c = hgetch();
- X habort();
- X }
- X }
- X
- X /* get the event */
- X
- X if (!(eline = getevent(defev = ev)))
- X habort();
- X
- X /* extract the relevant arguments */
- X
- X argc = getargc(eline);
- X if (c == ':')
- X {
- X cflag = 1;
- X c = hgetch();
- X }
- X if (c == '*')
- X {
- X farg = 1;
- X larg = argc;
- X cflag = 0;
- X }
- X else
- X {
- X hungetch(c);
- X larg = farg = getargspec(argc,marg);
- X if (larg == -2)
- X habort();
- X if (farg != -1)
- X cflag = 0;
- X c = hgetch();
- X if (c == '*')
- X {
- X cflag = 0;
- X larg = argc;
- X }
- X else if (c == '-')
- X {
- X cflag = 0;
- X larg = getargspec(argc,marg);
- X if (larg == -2)
- X habort();
- X if (larg == -1)
- X larg = argc-1;
- X }
- X else
- X hungetch(c);
- X }
- X if (farg == -1)
- X farg = 0;
- X if (larg == -1)
- X larg = argc;
- X if (!(sline = getargs(eline,farg,larg)))
- X habort();
- X
- X /* do the modifiers */
- X
- X for(;;)
- X {
- X c = (cflag) ? ':' : hgetch();
- X cflag = 0;
- X if (c == ':')
- X {
- X int gbal = 0;
- X
- X if ((c = hgetch()) == 'g')
- X {
- X gbal = 1;
- X c = hgetch();
- X }
- X switch(c)
- X {
- X case 'p':
- X histdone = HISTFLAG_DONE|HISTFLAG_NOEXEC;
- X break;
- X case 'h':
- X if (!remtpath(&sline))
- X {
- X herrflush();
- X zerr("modifier failed: h",NULL,0);
- X habort();
- X }
- X break;
- X case 'e':
- X if (!rembutext(&sline))
- X {
- X herrflush();
- X zerr("modifier failed: e",NULL,0);
- X habort();
- X }
- X break;
- X case 'r':
- X if (!remtext(&sline))
- X {
- X herrflush();
- X zerr("modifier failed: r",NULL,0);
- X habort();
- X }
- X break;
- X case 't':
- X if (!remlpaths(&sline))
- X {
- X herrflush();
- X zerr("modifier failed: t",NULL,0);
- X habort();
- X }
- X break;
- X case 's':
- X {
- X int del;
- X char *ptr1,*ptr2;
- X
- X del = hgetch();
- X ptr1 = hdynread2(del);
- X if (!ptr1)
- X habort();
- X ptr2 = hdynread2(del);
- X if (strlen(ptr1))
- X {
- X if (hsubl)
- X free(hsubl);
- X hsubl = ptr1;
- X }
- X if (hsubr)
- X free(hsubr);
- X hsubr = ptr2;
- X }
- X case '&':
- X if (hsubl && hsubr)
- X subst(&sline,hsubl,hsubr,gbal);
- X else
- X {
- X herrflush();
- X zerr("no previous substitution with &",NULL,0);
- X habort();
- X }
- X break;
- X case 'q':
- X quote(&sline);
- X break;
- X case 'x':
- X quotebreak(&sline);
- X break;
- X case 'l':
- X downcase(&sline);
- X break;
- X case 'u':
- X upcase(&sline);
- X break;
- X default:
- X herrflush();
- X zerr("illegal modifier: %c",NULL,c);
- X habort();
- X break;
- X }
- X }
- X else
- X {
- X if (c != '}' || !bflag)
- X hungetch(c);
- X if (c != '}' && bflag)
- X {
- X zerr("'}' expected",NULL,0);
- X habort();
- X }
- X break;
- X }
- X }
- X
- X /* stuff the resulting string in the input queue and start over */
- X
- X lexstop = 0;
- X if (alstackind != MAXAL)
- X {
- X hungets(HISTMARK);
- X alstack[alstackind++] = NULL;
- X }
- X for (ptr = sline; *ptr; ptr++) {
- X if (ptr[0] == '\\' && ptr[1] == '!') chuck(ptr);
- X }
- X hungets(sline);
- X histdone |= HISTFLAG_DONE;
- X if (isset(HISTVERIFY)) histdone |= HISTFLAG_NOEXEC|HISTFLAG_RECALL;
- X goto tailrec;
- X}
- X
- X/* reset the alias stack for lexrestore () */
- X
- Xvoid clearalstack() /**/
- X{
- XAlias ix;
- X
- X while (alstackind)
- X {
- X ix = alstack[--alstackind];
- X ix->inuse = 0;
- X }
- X}
- X
- X/* get a character without history expansion */
- X
- Xint hgetch() /**/
- X{
- Xunsigned char *line,*pmpt,*pmpt2 = NULL;
- Xint plen;
- X
- Xstart:
- X if (inbufct)
- X {
- X inbufct--;
- X if ((lastc = *inbufptr++) == ALPOP)
- X {
- X Alias ix;
- X char *t;
- X
- X if (!alstackind)
- X {
- X zerr("alias stack underflow",NULL,0);
- X errflag = lexstop = 1;
- X return lastc = ' ';
- X }
- X ix = alstack[--alstackind];
- X if (ix)
- X {
- X ix->inuse = 0;
- X t = ix->text;
- X if (*t && t[strlen(t)-1] == ' ')
- X alstat = ALSTAT_MORE;
- X else
- X alstat = ALSTAT_JUNK;
- X }
- X goto start;
- X }
- X if (itok(lastc))
- X goto start;
- X return lastc;
- X }
- X if (strin || errflag)
- X {
- X lexstop = 1;
- X return lastc = ' ';
- X }
- X if (interact && isset(SHINSTDIN))
- X if (!isfirstln)
- X pmpt = (unsigned char *)putprompt(prompt2,&plen);
- X else
- X {
- X int foo;
- X
- X pmpt = (unsigned char *)putprompt(prompt,&plen);
- X pmpt2 = (unsigned char *)((rprompt) ? putprompt(rprompt,&foo) : NULL);
- X }
- X if (!(interact && isset(SHINSTDIN) && SHTTY != -1 && isset(USEZLE))) {
- X char *lbuf;
- X if (interact && isset(SHINSTDIN))
- X write(2,pmpt,strlen((char *) pmpt));
- X line = (unsigned char *)fgets(lbuf = zalloc(256),256,bshin);
- X if (!line) free(lbuf);
- X } else
- X line = zleread(pmpt,pmpt2,plen);
- X if (!line) {
- X lexstop = 1;
- X return lastc = ' ';
- X }
- X if (errflag) {
- X free(line);
- X lexstop = errflag = 1;
- X return lastc = ' ';
- X }
- X if (interact && isset(SHINSTDIN)) {
- X char *s = curhistent->lit;
- X curhistent->lit = hp_concat(s,(char*)line);
- X }
- X if (isfirstln) spaceflag = *line == ' ';
- X if (isset(VERBOSE)) {
- X fputs((char *) line,stderr);
- X fflush(stderr);
- X }
- X if (*line && line[strlen((char *) line)-1] == '\n')
- X {
- X lineno++;
- X if (interact && isset(SUNKEYBOARDHACK) && isset(SHINSTDIN) &&
- X SHTTY != -1 && *line && line[1] &&
- X line[strlen((char *) line)-2] == '`')
- X {
- X int ct;
- X unsigned char *ptr;
- X
- X for (ct = 0, ptr = line; *ptr; ptr++)
- X if (*ptr == '`')
- X ct++;
- X if (ct & 1)
- X {
- X ptr[-2] = '\n';
- X ptr[-1] = '\0';
- X }
- X }
- X }
- X isfirstch = 1;
- X hungets((char*)line);
- X free(line);
- X goto start;
- X}
- X
- X/* Read one line of at most n-1 chars from the input queue */
- X
- Xchar *hgets(buf, n) /**/
- Xchar *buf;int n;
- X{
- Xint l;
- X
- X for (l = 0; l < n-1; l++)
- X if ((buf[l] = hgetch()) == '\n' || lexstop)
- X break;
- X buf[l+(lexstop?0:1)] = 0;
- X
- X return (!lexstop || l) ? buf : NULL;
- X}
- X
- X/* put a string in the input queue */
- X
- Xvoid hungets(str) /**/
- Xchar *str;
- X{
- Xint slen = strlen(str);
- X
- X/* shrink inbuf if it gets too big */
- X
- X if (!inbufct && inbufsz > 65536)
- X {
- X free(inbuf);
- X inbuf = zalloc(inbufsz = 256);
- X inbufptr = inbuf+inbufsz;
- X inbufct = 0;
- X }
- X if (slen+inbufct > inbufsz)
- X {
- X char *x;
- X
- X while (slen+inbufct > inbufsz)
- X inbufsz *= 4;
- X x = zalloc(inbufsz);
- X memcpy(x+inbufsz-inbufct,inbufptr,inbufct);
- X inbufptr = x+inbufsz-inbufct;
- X free(inbuf);
- X inbuf = x;
- X }
- X memcpy(inbufptr -= slen,str,slen);
- X inbufct += slen;
- X}
- X
- X/* unget a char and remove it from hline */
- X
- Xvoid hungetc(c) /**/
- Xint c;
- X{
- X if (lexstop)
- X return;
- X if (hlastw) {
- SHAR_EOF
- true || echo 'restore of zsh2.2/src/hist.c failed'
- fi
- echo 'End of zsh2.2 part 8'
- echo 'File zsh2.2/src/hist.c is continued in part 9'
- echo 9 > _shar_seq_.tmp
- exit 0
-
- exit 0 # Just in case...
-